package com.example.spring_rabbit.RedisConfig;

/**
 * @author wangc
 * @date 2022/9/5 15:49
 */
import io.lettuce.core.resource.DefaultClientResources;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.ObjectUtils;
 
import java.time.Duration;
 
@Configuration
public class RedisConfig {
 
    @Value("${redis.database.db0}")
    private int db0;
 
    @Value("${redis.database.db1}")
    private int db1;
 
    @Value("${redis.database.db2}")
    private int db2;
 
    @Value("${redis.database.db3}")
    private int db3;
 
    @Value("${spring.redis.host}")
    private String host;
 
    @Value("${spring.redis.port}")
    private int port;
 
    @Value("${spring.redis.password}")
    private String password;
 
    @Value("${spring.redis.lettuce.pool.max-active}")
    private int maxActive;
 
    @Value("${spring.redis.lettuce.pool.max-wait}")
    private int maxWait;
 
    @Value("${spring.redis.lettuce.pool.max-idle}")
    private int maxIdle;
 
    @Value("${spring.redis.lettuce.pool.min-idle}")
    private int minIdle;
 
    @Value("${spring.redis.timeout}")
    private long timeout;
 
    /**
     * 配置redis连接池
     */
    @Bean
    public GenericObjectPoolConfig poolConfig() {
        GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
        poolConfig.setMaxTotal(maxActive);
        poolConfig.setMaxIdle(maxIdle);
        poolConfig.setMinIdle(minIdle);
        poolConfig.setMaxWaitMillis(maxWait);
        return poolConfig;
    }
 
    /**
     * 配置默认客户端资源
     */
    @Bean("defaultClientResources")
    public  DefaultClientResources getDefaultClientResources(){
        return DefaultClientResources.create();
    }

    private StringRedisTemplate getStringRedisTemplate(int database, GenericObjectPoolConfig poolConfig, DefaultClientResources defaultClientResources) {
        // 构建工厂对象
        RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
        config.setHostName(host);
        config.setPort(port);
        if (!ObjectUtils.isEmpty(password)) {
            RedisPassword redisPassword = RedisPassword.of(password);
            config.setPassword(redisPassword);
        }
        LettucePoolingClientConfiguration clientConfig = LettucePoolingClientConfiguration.builder()
                .commandTimeout(Duration.ofSeconds(timeout))
                .poolConfig(poolConfig)
                .clientResources(defaultClientResources)
                .build();
        LettuceConnectionFactory factory = new LettuceConnectionFactory(config, clientConfig);
        // 设置使用的redis数据库
        factory.setDatabase(database);
        // 重新初始化工厂
        factory.afterPropertiesSet();
        return new StringRedisTemplate(factory);
    }
 
    @Bean(name="redisTemplateDb0")
    public StringRedisTemplate redisTemplateDefault(GenericObjectPoolConfig poolConfig,
                                                    @Qualifier("defaultClientResources") DefaultClientResources defaultClientResources) {
        return getStringRedisTemplate(db0, poolConfig,defaultClientResources);
    }
 
    @Bean(name="redisTemplateDb1")
    public StringRedisTemplate redisTemplateSort(GenericObjectPoolConfig poolConfig,
                                                 @Qualifier("defaultClientResources") DefaultClientResources defaultClientResources) {
        return getStringRedisTemplate(db1, poolConfig,defaultClientResources);
    }
 
    @Bean(name="redisTemplateDb2")
    public StringRedisTemplate redisTemplateCacheDrug(GenericObjectPoolConfig poolConfig,
                                                      @Qualifier("defaultClientResources") DefaultClientResources defaultClientResources) {
        return getStringRedisTemplate(db2, poolConfig,defaultClientResources);
    }
 
    @Bean(name="redisTemplateDb3")
    public StringRedisTemplate redisTemplateHistory(GenericObjectPoolConfig poolConfig,
                                                    @Qualifier("defaultClientResources") DefaultClientResources defaultClientResources) {
        return getStringRedisTemplate(db3, poolConfig,defaultClientResources);
    }
}